#pragma once
#include "comm/types.h"
#include "cpu/cpu.h"
#include "tools/list.h"
#include "comm/cpu_instr.h"
#include "fs/file.h"


#define TASK_TIME_SLICE_DEFAULT 10   //时间片

#define TASK_NAME_SIZE 32

#define TASK_FLAG_SYSTEAM  1
//进程可打开的文件
#define TASK_OPENFILE_SIZE 28
//任务状态
enum task_state{TASK_CREATED,TASK_RUNNING,TASK_SLEEP,TASK_READY,TASK_WAITTING,TASK_ZOMBIE};



typedef struct _task_args_t 
{
	uint32_t ret_addr;		// 返回地址，无用
	uint32_t argc;
	char **argv;
}task_args_t;


typedef struct task_t
{
    enum task_state state;

    int time_ticks;
    int slice_ticks;
    int sleep_ticks;

    int status;                 //返回值

    struct task_t* parent;
    int pid;

    uint32_t heap_start;
    uint32_t heap_end;

    char name[TASK_NAME_SIZE];
    //uint32_t* stack;
    list_node   run_node;       //readylise
    list_node   all_node;       //task_list
    list_node   wait_node;

    file_t* file_table[TASK_OPENFILE_SIZE];

    tss_t tss;                  //TSS任务段
    int tss_sel;                //TSS选择子

}task_t;

//任务切换
void task_switch_from_to(task_t* from,task_t* to);

//任务初始化
int task_init(task_t* task,int flag,const char* name,uint32_t entry,uint32_t esp);

//另一种任务切换方式
void simple_switch(uint32_t** from_stack,uint32_t* to_stack);

//任务管理器
typedef struct task_mananger_t
{
    task_t* cur_task;

    list ready_list;       //就绪队列
    list task_list;        //所有队列 
    list sleep_list;       //睡眠队列 

    task_t first_task;
    task_t idle_task;

    int app_code_sel;   //进程代码段选择子
    int app_data_sel;   //进程数据段选择子
}task_mananger_t;

void task_mananger_init();
void task_first_init();
task_t* task_first();
void task_set_block(task_t* task);
void task_set_ready(task_t* task);
int sys_sched_yield();
void task_dispatch();
void task_time_tick();

void task_set_sleep(task_t* task,uint32_t ticks);
void task_set_wakeup(task_t* task);
void sys_sleep(uint32_t ms);
task_t* cur_task();
int sys_getpid();
int sys_fork();
int sys_execve(char* name,char** argv,char** env);

file_t * task_file (int fd);
int task_alloc_fd (file_t * file);
void task_remove_fd (int fd);


void sys_exit(int status);
int sys_wait(int* status);